package com.yl.chainStore.control.statistical

import cn.hutool.core.map.MapUtil
import com.yl.chainStore.common.Constants
import com.yl.chainStore.common.enums.Status
import com.yl.chainStore.common.enums.TypeEnum
import com.yl.chainStore.control.BaseCtrl
import com.yl.chainStore.pojo.dto.statistical.StatisticalBalanceInLogByTypeDto
import com.yl.chainStore.pojo.dto.statistical.StatisticalBalanceInLogDto
import com.yl.chainStore.pojo.vo.statistical.CheckTheCalendarSelectVo
import com.yl.chainStore.pojo.vo.statistical.DailyCheckForSelectVo
import com.yl.chainStore.pojo.vo.statistical.IncomeSummarySelectVo
import com.yl.chainStore.pojo.vo.statistical.ReconciliationSelectVo
import com.yl.chainStore.services.ICustomerInfoService
import com.yl.chainStore.services.pay.IPayCustomerOrderService
import com.yl.chainStore.services.statistical.IPayStatisticalService
import com.yl.chainStore.util.dateFormat
import com.yl.chainStore.util.getDays
import com.yl.chainStore.util.getFirstDayByMonth
import com.yl.chainStore.util.getLastDayByMonth
import com.yl.common.ErrorCode
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnError
import com.yl.common.control.returnSuccess
import com.yl.common.getContext
import com.yl.users.common.enum.UserPackageTypeEnum
import com.yl.users.services.ICompanyUserService
import org.springframework.beans.factory.annotation.Value
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
import javax.servlet.http.HttpServletResponse

/**
 * 付款统计相关
 */
@RestController
@RequestMapping("statistical/pay")
open class PayStatisticalController(
    private val iPayStatisticalService: IPayStatisticalService,
    private val iPayCustomerOrderService: IPayCustomerOrderService,
    private val iCompanyUserService: ICompanyUserService,
    private val iCustomerInfoService: ICustomerInfoService
) : BaseCtrl() {

    //绝对路径
    @Value("\${config.file-save-path}")
    private lateinit var resources: String

    /**
     * 收入汇总
     */
    @PostMapping("incomeSummary")
    @Transactional
    open fun incomeSummary(@RequestBody vo: IncomeSummarySelectVo): ResponseBody {
        val days = getDays(dateFormat(vo.startTime), dateFormat(vo.endTime))
        if (days.size > 50) {
            returnError(ErrorCode.QUERY_PARAM_ERROR, "开始与结束时间间隔过长")
        }
        vo.subCompanyId = getContext().subCompanyId
        vo.companyId = getContext().companyId
        vo.orderStatuses = listOf(Status.WAIT_PAY, Status.PAYING, Status.END)
        vo.orderDesc = true
        //返回参数
        val resMap = mutableMapOf<String, Any>()
        //标题
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "日期"), Pair("name", "day")))
        titleList.add(mutableMapOf(Pair("show", "应付"), Pair("name", "originalSumMoney")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))

        //结果数据
        val dataList = mutableListOf<MutableMap<String, Any>>()

        //订单记录 (应付金额)
        val orderStatisticalByDay = iPayStatisticalService.getOrderStatisticalByDay(vo)
        //实际收款
        val customerOrderPayLogDetailByDay = iPayStatisticalService.getCustomerOrderPayLogDetailByDay(vo)
        //馈赠金使用
        val giftUseByDay = iPayStatisticalService.getCustomerOrderUseGiftMoneyByDay(vo)

        val refundMoneyByDay = iPayStatisticalService.getCustomerOrderRefundByDay(vo)
        if (refundMoneyByDay.isNotEmpty()) {
            titleList.add(mutableMapOf(Pair("show", "退款"), Pair("name", "refundMoney")))
        }
        var orderStatisticalByDayIndex = 0
        var customerOrderPayLogDetailByDayIndex = 0
        //统计栏 顺便记录 收款类型标题(不包含前面部分)
        val dataPayTypeSet = mutableSetOf<TypeEnum>()
        for (i in days.size - 1 downTo 0) {
            //单组数据拼装
            val resDataMap = mutableMapOf<String, Any>()
            val dayStr = days[i]
            resDataMap["day"] = dayStr
            //应付 订单里面拿
            var originalSumMoney = 0L
            if (orderStatisticalByDayIndex < orderStatisticalByDay.size) {
                val orderStatistical = orderStatisticalByDay[orderStatisticalByDayIndex]

                if (orderStatistical.createDay == dayStr) {
                    originalSumMoney = orderStatistical.originalSumMoney
                    orderStatisticalByDayIndex++
                }
            }
            resDataMap["originalSumMoney"] = showMoney(originalSumMoney)
            if (refundMoneyByDay.isNotEmpty()) {
                val refund = refundMoneyByDay[dayStr] ?: 0L
                resDataMap["refundMoney"] = showMoney(refund)
            }

            //付款
            var inSumMoney = 0L
            //先全部默认有0金额
            for (title in dataPayTypeSet) {
                resDataMap[title.typeName] = showMoney(0L)
            }
            if (customerOrderPayLogDetailByDayIndex < customerOrderPayLogDetailByDay.size) {
                val customerBalanceInLog = customerOrderPayLogDetailByDay[customerOrderPayLogDetailByDayIndex]
                if (customerBalanceInLog.payDay == dayStr) {
                    customerOrderPayLogDetailByDayIndex++
                    if (customerBalanceInLog.payList != null) {
                        inSumMoney = setPayMoney(
                            customerBalanceInLog.payList,
                            resDataMap,
                            dataPayTypeSet, titleList, dataList,
                            giftUseByDay,
                            dayStr,
                        )
                    }
                }
            }


            resDataMap["inSumMoney"] = showMoney(inSumMoney)
            dataList.add(resDataMap)
        }

        resMap["title"] = titleList
        resMap["data"] = dataList
        return returnSuccess(resMap)
    }

    /**
     * 收入汇总导出
     */
    @PostMapping("incomeSummaryExport")
    @Transactional
    open fun incomeSummaryExport(@RequestBody vo: IncomeSummarySelectVo,response: HttpServletResponse) {
        val days = getDays(dateFormat(vo.startTime), dateFormat(vo.endTime))
        if (days.size > 50) {
            returnError(ErrorCode.QUERY_PARAM_ERROR, "开始与结束时间间隔过长")
        }
        vo.subCompanyId = getContext().subCompanyId
        vo.companyId = getContext().companyId
        vo.orderStatuses = listOf(Status.WAIT_PAY, Status.PAYING, Status.END)
        vo.orderDesc = true
        //返回参数
        val resMap = mutableMapOf<String, Any>()
        //标题
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "日期"), Pair("name", "day")))
        titleList.add(mutableMapOf(Pair("show", "应付"), Pair("name", "originalSumMoney")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))

        //结果数据
        val dataList = mutableListOf<MutableMap<String, Any>>()

        //订单记录 (应付金额)
        val orderStatisticalByDay = iPayStatisticalService.getOrderStatisticalByDay(vo)
        //实际收款
        val customerOrderPayLogDetailByDay = iPayStatisticalService.getCustomerOrderPayLogDetailByDay(vo)
        //馈赠金使用
        val giftUseByDay = iPayStatisticalService.getCustomerOrderUseGiftMoneyByDay(vo)

        val refundMoneyByDay = iPayStatisticalService.getCustomerOrderRefundByDay(vo)
        if (refundMoneyByDay.isNotEmpty()) {
            titleList.add(mutableMapOf(Pair("show", "退款"), Pair("name", "refundMoney")))
        }
        var orderStatisticalByDayIndex = 0
        var customerOrderPayLogDetailByDayIndex = 0
        //统计栏 顺便记录 收款类型标题(不包含前面部分)
        val dataPayTypeSet = mutableSetOf<TypeEnum>()
        for (i in days.size - 1 downTo 0) {
            //单组数据拼装
            val resDataMap = mutableMapOf<String, Any>()
            val dayStr = days[i]
            resDataMap["day"] = dayStr
            //应付 订单里面拿
            var originalSumMoney = 0L
            if (orderStatisticalByDayIndex < orderStatisticalByDay.size) {
                val orderStatistical = orderStatisticalByDay[orderStatisticalByDayIndex]

                if (orderStatistical.createDay == dayStr) {
                    originalSumMoney = orderStatistical.originalSumMoney
                    orderStatisticalByDayIndex++
                }
            }
            resDataMap["originalSumMoney"] = showMoney(originalSumMoney)
            if (refundMoneyByDay.isNotEmpty()) {
                val refund = refundMoneyByDay[dayStr] ?: 0L
                resDataMap["refundMoney"] = showMoney(refund)
            }

            //付款
            var inSumMoney = 0L
            //先全部默认有0金额
            for (title in dataPayTypeSet) {
                resDataMap[title.typeName] = showMoney(0L)
            }
            if (customerOrderPayLogDetailByDayIndex < customerOrderPayLogDetailByDay.size) {
                val customerBalanceInLog = customerOrderPayLogDetailByDay[customerOrderPayLogDetailByDayIndex]
                if (customerBalanceInLog.payDay == dayStr) {
                    customerOrderPayLogDetailByDayIndex++
                    if (customerBalanceInLog.payList != null) {
                        inSumMoney = setPayMoney(
                                customerBalanceInLog.payList,
                                resDataMap,
                                dataPayTypeSet, titleList, dataList,
                                giftUseByDay,
                                dayStr,
                        )
                    }
                }
            }


            resDataMap["inSumMoney"] = showMoney(inSumMoney)
            dataList.add(resDataMap)
        }

        resMap["title"] = titleList
        resMap["data"] = dataList
        //导出
        val headAlias: MutableMap<String?, String?> = MapUtil.newHashMap(true)
        for ( map in titleList){
            headAlias[map["name"].toString()]= map["show"].toString()
        }
        export(response,dataList,headAlias)
    }


    /**
     * 现金流
     */
    @PostMapping("cashFlowHaveType")
    @Transactional
    open fun cashFlowHaveType(@RequestBody vo: IncomeSummarySelectVo): ResponseBody {
        return if (vo.selectType == TypeEnum.INCOME_SUMMARY_SELECT_TYPE_DETAIL) {
            cashFlowByDetail(vo)
        } else {
            cashFlow(vo)
        }
    }

    /**
     * 现金流（汇总）
     */
    @PostMapping("cashFlow")
    @Transactional
    open fun cashFlow(@RequestBody vo: IncomeSummarySelectVo): ResponseBody {
        val days = getDays(dateFormat(vo.startTime), dateFormat(vo.endTime))
        if (days.size > 50) {
            returnError(ErrorCode.QUERY_PARAM_ERROR, "开始与结束时间间隔过长")
        }
        vo.subCompanyId = getContext().subCompanyId
        vo.companyId = getContext().companyId
        vo.orderDesc = true
//		vo.orderStatuses = listOf(Status.WAIT_PAY, Status.PAYING, Status.END)
        //返回参数
        val resMap = mutableMapOf<String, Any>()

        //标题
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "日期"), Pair("name", "day")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))
        //结果数据
        val dataList = mutableListOf<MutableMap<String, Any>>()
        //充值
        val customerBalanceInLogByDay = iPayStatisticalService.getCustomerBalanceInLogByDay(vo)
        var customerBalanceInLogByDayIndex = 0
        //付款类型相关标题
        val dataPayTypeSet = mutableSetOf<TypeEnum>()
        for (i in days.size - 1 downTo 0) {
            //单组数据拼装
            val resDataMap = mutableMapOf<String, Any>()
            val dayStr = days[i]
            resDataMap["day"] = dayStr
            //充值
            var inSumMoney = 0L
            for (title in dataPayTypeSet) {
                resDataMap[title.typeName] = showMoney(0L)
            }
            if (customerBalanceInLogByDayIndex < customerBalanceInLogByDay.size) {
                val customerBalanceInLog = customerBalanceInLogByDay[customerBalanceInLogByDayIndex]
                if (customerBalanceInLog.payDay == dayStr) {
                    customerBalanceInLogByDayIndex++
                    if (customerBalanceInLog.payList != null) {
                        inSumMoney = setPayMoney(
                            customerBalanceInLog.payList,
                            resDataMap,
                            dataPayTypeSet, titleList, dataList,
                            null,
                            dayStr
                        )
                    }
                }
            }
            resDataMap["inSumMoney"] = showMoney(inSumMoney)
            dataList.add(resDataMap)
        }
        resMap["title"] = titleList
        resMap["data"] = dataList
        return returnSuccess(resMap)
    }

    /**
     * 现金流导出
     */
    @PostMapping("/cashFlowExport")
    @Transactional
    open fun cashFlowExport(@RequestBody vo: IncomeSummarySelectVo,response: HttpServletResponse) {
        val days = getDays(dateFormat(vo.startTime), dateFormat(vo.endTime))
        if (days.size > 50) {
            returnError(ErrorCode.QUERY_PARAM_ERROR, "开始与结束时间间隔过长")
        }
        vo.subCompanyId = getContext().subCompanyId
        vo.companyId = getContext().companyId
        vo.orderDesc = true
//		vo.orderStatuses = listOf(Status.WAIT_PAY, Status.PAYING, Status.END)
        //返回参数
        val resMap = mutableMapOf<String, Any>()

        //标题
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "日期"), Pair("name", "day")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))
        //结果数据
        val dataList = mutableListOf<MutableMap<String, Any>>()
        //充值
        val customerBalanceInLogByDay = iPayStatisticalService.getCustomerBalanceInLogByDay(vo)
        var customerBalanceInLogByDayIndex = 0
        //付款类型相关标题
        val dataPayTypeSet = mutableSetOf<TypeEnum>()
        for (i in days.size - 1 downTo 0) {
            //单组数据拼装
            val resDataMap = mutableMapOf<String, Any>()
            val dayStr = days[i]
            resDataMap["day"] = dayStr
            //充值
            var inSumMoney = 0L
            for (title in dataPayTypeSet) {
                resDataMap[title.typeName] = showMoney(0L)
            }
            if (customerBalanceInLogByDayIndex < customerBalanceInLogByDay.size) {
                val customerBalanceInLog = customerBalanceInLogByDay[customerBalanceInLogByDayIndex]
                if (customerBalanceInLog.payDay == dayStr) {
                    customerBalanceInLogByDayIndex++
                    if (customerBalanceInLog.payList != null) {
                        inSumMoney = setPayMoney(
                                customerBalanceInLog.payList,
                                resDataMap,
                                dataPayTypeSet, titleList, dataList,
                                null,
                                dayStr
                        )
                    }
                }
            }
            resDataMap["inSumMoney"] = showMoney(inSumMoney)
            dataList.add(resDataMap)
        }
        resMap["title"] = titleList
        resMap["data"] = dataList
        //导出
        val headAlias: MutableMap<String?, String?> = MapUtil.newHashMap(true)
        for ( map in titleList){
            headAlias[map["name"].toString()]= map["show"].toString()
        }
        export(response,dataList, headAlias)
    }

    /**
     * 现金流（明细）
     */
    @PostMapping("cashFlowByDetail")
    @Transactional
    open fun cashFlowByDetail(@RequestBody vo: IncomeSummarySelectVo): ResponseBody {
        vo.subCompanyId = getContext().subCompanyId
        vo.companyId = getContext().companyId

        //充值
        vo.useType = TypeEnum.PAY_TYPE_TOP_UP
        val balanceInLogList = iPayStatisticalService.getCustomerBalanceInLogByPayType(vo)
        //订单付款(诊疗收费)
        vo.payType = TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_NORMAL
        val orderPayList = iPayStatisticalService.getCustomerOrderPayLogSumMoneyByPayType(vo)
        //订单付欠款(诊疗收欠费)
        vo.payType = TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_OWE
        val oweList = iPayStatisticalService.getCustomerOrderPayLogSumMoneyByPayType(vo)
        //订单退款(诊疗退费)
        vo.useType = TypeEnum.PAY_TYPE_ORDER_REFUND
        val orderRefund = iPayStatisticalService.getBalanceOutLogGroupByPayType(vo)
        //余额退现
        vo.useType = TypeEnum.PAY_TYPE_BALANCE_REFUND
        val balanceRefund = iPayStatisticalService.getBalanceOutLogGroupByPayType(vo)

        val payTypeActualPaymentMap = mutableMapOf<TypeEnum, Long>()
        val dataMap = mutableMapOf<TypeEnum, MutableMap<String, Long>>()
        eachStatisticalBalanceInLogByTypeList(orderPayList, payTypeActualPaymentMap, dataMap, "诊疗收费")
        eachStatisticalBalanceInLogByTypeList(oweList, payTypeActualPaymentMap, dataMap, "诊疗收欠费")
        eachStatisticalBalanceInLogByTypeList(orderRefund, payTypeActualPaymentMap, dataMap, "诊疗退费")
        eachStatisticalBalanceInLogByTypeList(balanceInLogList, payTypeActualPaymentMap, dataMap, "余额充值")
        eachStatisticalBalanceInLogByTypeList(balanceRefund, payTypeActualPaymentMap, dataMap, "余额退费")

        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "付款方式"), Pair("name", "payType")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "payment")))
        titleList.add(mutableMapOf(Pair("show", "诊疗收费"), Pair("name", "诊疗收费")))
        titleList.add(mutableMapOf(Pair("show", "诊疗收欠费"), Pair("name", "诊疗收欠费")))
        titleList.add(mutableMapOf(Pair("show", "诊疗退费"), Pair("name", "诊疗退费")))
        titleList.add(mutableMapOf(Pair("show", "余额充值"), Pair("name", "余额充值")))
        titleList.add(mutableMapOf(Pair("show", "余额退费"), Pair("name", "余额退费")))

        val data = mutableListOf<Map<String, Any>>()
        for ((type, value) in dataMap) {

            val resMap = mutableMapOf<String, Any>()
            resMap["payType"] = type.typeName
            resMap["payment"] = showMoney(payTypeActualPaymentMap[type]!!)
            for ((title, money) in value) {
                resMap[title] = showMoney(money)
            }
            data.add(resMap)
        }

        val resMap = mutableMapOf<String, Any>()
        resMap["title"] = titleList
        resMap["data"] = data
        return returnSuccess(resMap)
    }


    /**
     * 对账日历
     */
    @PostMapping("checkTheCalendar")
    @Transactional
    open fun checkTheCalendar(@RequestBody vo: CheckTheCalendarSelectVo): ResponseBody {
        if (vo.month == null) {
            vo.month = Date()
        }
        val startTime = getFirstDayByMonth(vo.month!!)
        val endTime = getLastDayByMonth(vo.month!!)
        val days = getDays(dateFormat(startTime), dateFormat(endTime))
        val orderStatisticalByDay = iPayStatisticalService.getOrderStatisticalByDay(
            IncomeSummarySelectVo(
                startTime = startTime,
                endTime = endTime,
                subCompanyId = getContext().subCompanyId,
                companyId = getContext().companyId
            )
        )
        val customerOrderPayLogSumMoneyByDay = iPayStatisticalService.getCustomerOrderPayLogSumMoneyByDay(
            IncomeSummarySelectVo(
                startTime = startTime,
                endTime = endTime,
                subCompanyId = getContext().subCompanyId,
                companyId = getContext().companyId
            )
        )
        val resList = mutableListOf<Map<String, Any>>()
        var originalSumMoneyIndex = 0
        var payIndex = 0
        for (day in days) {
            val resMap = mutableMapOf<String, Any>()
            resMap["day"] = day
            resMap["owe"] = showMoney(0L)
            var payMoney = 0L
            //应付金额
            if (originalSumMoneyIndex < orderStatisticalByDay.size) {
                if (day == orderStatisticalByDay[originalSumMoneyIndex].createDay) {
                    payMoney = orderStatisticalByDay[originalSumMoneyIndex].originalSumMoney

                    originalSumMoneyIndex++
                }
            }
            resMap["payMoney"] = showMoney(payMoney)
            //应付金额减去实际付款 就是欠款的变动
            if (payIndex < customerOrderPayLogSumMoneyByDay.size) {
                if (day == customerOrderPayLogSumMoneyByDay[payIndex].payDay) {
                    resMap["owe"] = showMoney(payMoney.minus(customerOrderPayLogSumMoneyByDay[payIndex].paySumMoney))
                    payIndex++
                }
            }
            resList.add(resMap)
        }


        return returnSuccess(resList)
    }

    /**
     * 每日对账
     */
    @PostMapping("dailyCheck")
    open fun dailyCheck(@RequestBody vo: DailyCheckForSelectVo): ResponseBody {
        if (vo.dayString == null) {
            vo.dayString = SimpleDateFormat("yyyy-MM-dd").format(Date())
        }
        return if (vo.byUserType == UserPackageTypeEnum.COMPANY_USER_TYPE_CASHIER) {
            dailyCheckForCashier(vo)
        } else {
            dailyCheckForDoctor(vo)
        }
    }

    /**
     * 每日对账导出
     */
    @PostMapping("dailyCheckExport")
    open fun dailyCheckExport(@RequestBody vo: DailyCheckForSelectVo): ResponseBody {
        if (vo.dayString == null) {
            vo.dayString = SimpleDateFormat("yyyy-MM-dd").format(Date())
        }
        return if (vo.byUserType == UserPackageTypeEnum.COMPANY_USER_TYPE_CASHIER) {
            dailyCheckForCashier(vo)
        } else {
            dailyCheckForDoctor(vo)
        }
    }

    /**
     * 每日对账 （医生）
     */
    @PostMapping("dailyCheckForDoctor")
    @Transactional
    open fun dailyCheckForDoctor(@RequestBody vo: DailyCheckForSelectVo): ResponseBody {
        val orderPayLog = iPayStatisticalService.getPayCustomerOrderPayAndRefundLog(vo)
        val resMap = mutableMapOf<String, Any>()
        //标题栏
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "患者姓名"), Pair("name", "customerName")))
        titleList.add(mutableMapOf(Pair("show", "收费时间"), Pair("name", "payTime")))
        titleList.add(mutableMapOf(Pair("show", vo.byUserType!!.typeName), Pair("name", "selectUserName")))
        titleList.add(mutableMapOf(Pair("show", "就诊时间"), Pair("name", "orderTime")))
        titleList.add(mutableMapOf(Pair("show", "应付"), Pair("name", "originalSumMoney")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))
        //最外层内容栏目
        val dataList = mutableListOf<Map<String, Any?>>()

        //医生账单记录
        val userPayLogMap = mutableMapOf<Long, MutableList<MutableMap<String, Any>>>()

        //用户
        val userMap = mutableMapOf<Long, String>()

        //付款类型
        val dataDataPayTypeSet = mutableSetOf<TypeEnum>()
        for (payLog in orderPayLog) {
            if (payLog.type != TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_REFUND) {
                //订单
                val order = iPayCustomerOrderService.getOrderInfo(payLog.orderId) ?: continue
                val orderDetails = iPayCustomerOrderService.getOrderDetails(payLog.orderId)
                //应付金额处理
                var orderOriginalSumMoney = 0L
                //医生id
                val userOriginalSumMoneyMap = mutableMapOf<Long, Long>()
                for (detail in orderDetails) {
                    //本张订单金额处理
                    orderOriginalSumMoney += detail.itemSumMoney

                    val userId = when (vo.byUserType) {
                        UserPackageTypeEnum.COMPANY_USER_TYPE_DOCTOR -> {
                            detail.doctorId
                        }
                        UserPackageTypeEnum.COMPANY_USER_TYPE_CONSULT -> {
                            detail.consultantId
                        }
                        UserPackageTypeEnum.COMPANY_USER_TYPE_ONLINE_MARKETING -> {
                            detail.netConsultantId
                        }
                        UserPackageTypeEnum.COMPANY_USER_TYPE_NURSE -> {
                            detail.netConsultantId
                        }
                        else -> null
                    }
                    if (userId != null) {
                        if (userOriginalSumMoneyMap[userId] == null) {
                            userOriginalSumMoneyMap[userId] = detail.itemSumMoney
                        } else {
                            userOriginalSumMoneyMap[userId] =
                                userOriginalSumMoneyMap[userId]!!.plus(detail.itemSumMoney)
                        }
                        //外层记录
                        if (userMap[userId] == null) {
                            val user = iCompanyUserService.getUser(userId)
                            userMap[userId] = user?.realName ?: ""
                            userPayLogMap[userId] = mutableListOf()
                        }
                    }

                }
                val customer = iCustomerInfoService.getById(order.customerId)
                val details = iPayCustomerOrderService.getPayLogDetailList(payLog.id)
                val giftsOfGold =
                    iCustomerInfoService.getGiftsOfGold(payLog.id, TypeEnum.PAY_TYPE_PAY_ORDER)
                for ((id, sumMoney) in userOriginalSumMoneyMap) {
                    val thisUserPayLogMap = mutableMapOf<String, Any>()
                    thisUserPayLogMap["customerName"] = customer?.name ?: ""
                    thisUserPayLogMap["payTime"] = payLog.payTime
                    thisUserPayLogMap["selectUserName"] = userMap[id] ?: ""
                    thisUserPayLogMap["orderTime"] = order.createTime

                    for (type in dataDataPayTypeSet) {
                        thisUserPayLogMap[type.typeName] = showMoney(0L)
                    }
                    //实际付款总额
                    var inSumMoney = 0L
                    //付款方式处理
                    for (detail in details) {
                        var payMoney = detail.payMoney
                        if (detail.payType == TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT) {
                            var giftSum = 0L
                            for (gift in giftsOfGold) {
                                giftSum += gift.money
                            }
                            if (giftSum != 0L) {
                                //有馈赠金
                                thisUserPayLogMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] =
                                    showMoney(giftSum, sumMoney, orderOriginalSumMoney)
                                if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                                    //添加标题
                                    titleList.add(
                                        mutableMapOf(
                                            Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                            Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                                        )
                                    )
                                    //付款类型添加
                                    dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                                    //之前行数据添加
                                    for ((_, list) in userPayLogMap) {
                                        for (logMap in list) {
                                            logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                                        }
                                    }
                                }
                                payMoney -= giftSum
                                inSumMoney += giftSum
                            }
                        }
                        thisUserPayLogMap[detail.payType.typeName] =
                            showMoney(payMoney, sumMoney, orderOriginalSumMoney)
                        inSumMoney += payMoney
                        if (!dataDataPayTypeSet.contains(detail.payType)) {
                            //添加标题
                            titleList.add(
                                mutableMapOf(
                                    Pair("show", detail.payType.typeName),
                                    Pair("name", detail.payType.typeName)
                                )
                            )
                            //付款类型添加
                            dataDataPayTypeSet.add(detail.payType)
                            //之前数据添加
                            for ((_, list) in userPayLogMap) {
                                for (logMap in list) {
                                    logMap[detail.payType.typeName] = showMoney(0L)
                                }
                            }
                        }
                    }
                    //实收
                    thisUserPayLogMap["inSumMoney"] = showMoney(inSumMoney, sumMoney, orderOriginalSumMoney)
                    if (payLog.type == TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_OWE) {
                        //欠款变动
                        thisUserPayLogMap["ownUpdate"] = showMoney(-inSumMoney, sumMoney, orderOriginalSumMoney)
                        thisUserPayLogMap["originalSumMoney"] = showMoney(0)
                    } else {
                        thisUserPayLogMap["ownUpdate"] =
                            showMoney(orderOriginalSumMoney - inSumMoney, sumMoney, orderOriginalSumMoney)
                        thisUserPayLogMap["originalSumMoney"] = showMoney(sumMoney)
                    }

                    thisUserPayLogMap["status"] = payLog.type
                    thisUserPayLogMap["remark"] = payLog.remark ?: ""
                    //添加到map里面去
                    userPayLogMap[id]!!.add(thisUserPayLogMap)
                }
            } else {
                if (payLog.money == 0L) {
                    continue
                }
                //退款
                val refundLogDetails = iPayCustomerOrderService.getRefundLogDetailList(payLog.id)
                if (refundLogDetails.isEmpty()) {
                    //退款必须要有退款明细
                    continue
                }
                //订单实际退款
                var orderRefundSumMoney = 0L
                val flowList = iCustomerInfoService.getCustomerMoneyFlowByAssociateId(
                    payLog.id,
                    TypeEnum.PAY_TYPE_ORDER_REFUND
                )
                for (flow in flowList) {
                    orderRefundSumMoney += flow.money
                }
                //余额退现
                val balanceToMoneyLogs = iCustomerInfoService.getBalanceToMoneyLogBYAssociateId(
                    payLog.id,
                    TypeEnum.PAY_TYPE_ORDER_REFUND_TO_MONEY
                )

                val order = iPayCustomerOrderService.getOrderInfo(payLog.orderId) ?: continue
                //应付金额处理
                var orderOriginalSumMoney = 0L
                //医生id -
                val userOriginalSumMoneyMap = mutableMapOf<Long, Long>()
                for (detail in refundLogDetails) {
                    //本张订单金额处理
                    orderOriginalSumMoney += detail.refundMoney
                    val orderDetail = iPayCustomerOrderService.getDetailById(detail.detailId) ?: continue
                    val userId = when (vo.byUserType) {
                        UserPackageTypeEnum.COMPANY_USER_TYPE_DOCTOR -> {
                            orderDetail.doctorId
                        }
                        UserPackageTypeEnum.COMPANY_USER_TYPE_CONSULT -> {
                            orderDetail.consultantId
                        }
                        UserPackageTypeEnum.COMPANY_USER_TYPE_ONLINE_MARKETING -> {
                            orderDetail.netConsultantId
                        }
                        UserPackageTypeEnum.COMPANY_USER_TYPE_NURSE -> {
                            orderDetail.netConsultantId
                        }
                        else -> null
                    }
                    if (userId != null) {
                        if (userOriginalSumMoneyMap[userId] == null) {
                            userOriginalSumMoneyMap[userId] = detail.refundMoney
                        } else {
                            userOriginalSumMoneyMap[userId] = userOriginalSumMoneyMap[userId]!!.plus(detail.refundMoney)
                        }
                        //外层记录
                        if (userMap[userId] == null) {
                            val user = iCompanyUserService.getUser(userId)
                            userMap[userId] = user?.realName ?: ""
                            userPayLogMap[userId] = mutableListOf()
                        }
                    }

                }
                val customer = iCustomerInfoService.getById(order.customerId)
                val giftsOfGold =
                    iCustomerInfoService.getGiftsOfGold(payLog.id, TypeEnum.PAY_TYPE_ORDER_REFUND)
                for ((id, sumMoney) in userOriginalSumMoneyMap) {
                    val thisUserPayLogMap = mutableMapOf<String, Any>()
                    thisUserPayLogMap["customerName"] = customer?.name ?: ""
                    thisUserPayLogMap["payTime"] = payLog.payTime
                    thisUserPayLogMap["selectUserName"] = userMap[id] ?: ""
                    thisUserPayLogMap["orderTime"] = order.createTime
                    //先默认每行为0
                    for (type in dataDataPayTypeSet) {
                        thisUserPayLogMap[type.typeName] = showMoney(0L)
                    }
                    //退现金记录
                    var balanceToMoneySum = 0L
                    for (log in balanceToMoneyLogs) {
                        val payMoney = log.money
                        thisUserPayLogMap[log.payType.typeName] =
                            showMoney(payMoney * -1, sumMoney, orderOriginalSumMoney)
                        balanceToMoneySum += payMoney
                        if (!dataDataPayTypeSet.contains(log.payType)) {
                            //添加标题
                            titleList.add(
                                mutableMapOf(
                                    Pair("show", log.payType.typeName),
                                    Pair("name", log.payType.typeName)
                                )
                            )
                            //付款类型添加
                            dataDataPayTypeSet.add(log.payType)
                            //之前数据添加
                            for ((_, list) in userPayLogMap) {
                                for (logMap in list) {
                                    logMap[log.payType.typeName] = showMoney(0L)
                                }
                            }
                        }
                    }

                    var gifts = 0L
                    for (gift in giftsOfGold) {
                        gifts += gift.money
                    }
                    if (gifts != 0L) {
                        thisUserPayLogMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] =
                            showMoney(gifts * -1, sumMoney, orderOriginalSumMoney)
                        if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                            //添加标题
                            titleList.add(
                                mutableMapOf(
                                    Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                    Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                                )
                            )
                            //付款类型添加
                            dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                            //之前行数据添加
                            for ((_, list) in userPayLogMap) {
                                for (logMap in list) {
                                    logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                                }
                            }
                        }
                    }

                    if (balanceToMoneySum != orderRefundSumMoney) {
                        //订单真实退款 - 退现金额 - 退馈赠金 = 退余额
                        var refundBalance = orderRefundSumMoney - balanceToMoneySum - gifts
                        thisUserPayLogMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] =
                            showMoney(refundBalance * -1, sumMoney, orderOriginalSumMoney)
                        if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)) {
                            //添加标题
                            titleList.add(
                                mutableMapOf(
                                    Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName),
                                    Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName)
                                )
                            )
                            //付款类型添加
                            dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)
                            //之前行数据添加
                            for ((_, list) in userPayLogMap) {
                                for (logMap in list) {
                                    logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] = showMoney(0L)
                                }
                            }
                        }

                    }
                    //应该付款
                    thisUserPayLogMap["originalSumMoney"] =
                        showMoney(payLog.money * -1, sumMoney, orderOriginalSumMoney)
                    //实际收款
                    thisUserPayLogMap["inSumMoney"] =
                        showMoney(orderRefundSumMoney * -1, sumMoney, orderOriginalSumMoney)
                    //欠款变动
                    thisUserPayLogMap["ownUpdate"] =
                        showMoney(orderRefundSumMoney - payLog.money, sumMoney, orderOriginalSumMoney)

                    thisUserPayLogMap["status"] = payLog.type
                    thisUserPayLogMap["remark"] = payLog.remark ?: ""
                    //添加到map里面去
                    userPayLogMap[id]!!.add(thisUserPayLogMap)
                }
            }
        }


        //结果整理
        for ((id, list) in userPayLogMap) {
            val userShowMap = mutableMapOf<String, Any?>()
            userShowMap["userName"] = userMap[id]
            userShowMap["list"] = list
            dataList.add(userShowMap)
        }
        titleList.add(mutableMapOf(Pair("show", "欠费变动"), Pair("name", "ownUpdate")))
        titleList.add(mutableMapOf(Pair("show", "状态"), Pair("name", "status")))
        titleList.add(mutableMapOf(Pair("show", "备注"), Pair("name", "remark")))
        resMap["title"] = titleList
        resMap["data"] = dataList
        return returnSuccess(resMap)
    }


    /**
     * 每日对账 （收银）
     */
    @PostMapping("dailyCheckForCashier")
    @Transactional
    open fun dailyCheckForCashier(@RequestBody vo: DailyCheckForSelectVo): ResponseBody {
        val orderPayLog = iPayStatisticalService.getPayCustomerOrderPayAndRefundLog(vo)
        val resMap = mutableMapOf<String, Any>()

        //标题栏
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "患者姓名"), Pair("name", "customerName")))
        titleList.add(mutableMapOf(Pair("show", "收费时间"), Pair("name", "payTime")))
        titleList.add(mutableMapOf(Pair("show", "收款人"), Pair("name", "cashierName")))
        titleList.add(mutableMapOf(Pair("show", "就诊时间"), Pair("name", "orderTime")))
        titleList.add(mutableMapOf(Pair("show", "应付"), Pair("name", "originalSumMoney")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))
        //最外层内容栏目
        val dataList = mutableListOf<Map<String, Any?>>()
        //医生账单记录
        val userPayLogMap = mutableMapOf<Long, MutableList<MutableMap<String, Any>>>()

        //用户
        val userMap = mutableMapOf<Long, String>()

        val dataDataPayTypeSet = mutableSetOf<TypeEnum>()
        for (payLog in orderPayLog) {
            if (payLog.type != TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_REFUND) {
                val orderInfo = iPayCustomerOrderService.getOrderInfo(payLog.orderId) ?: continue
                val originalSumMoney = if (payLog.type == TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_OWE) {
                    0
                } else {
                    orderInfo.orderDetailSumMoney
                }
                if (userMap[payLog.createUserId] == null) {
                    val user = iCompanyUserService.getUser(payLog.createUserId)
                    userMap[payLog.createUserId] = user?.realName ?: ""
                    userPayLogMap[payLog.createUserId] = mutableListOf()
                }
                val customer = iCustomerInfoService.getById(orderInfo.customerId)
                val thisUserPayLogMap = mutableMapOf<String, Any>()
                thisUserPayLogMap["customerName"] = customer?.name ?: ""
                thisUserPayLogMap["payTime"] = payLog.payTime
                thisUserPayLogMap["cashierName"] = userMap[payLog.createUserId] ?: ""
                thisUserPayLogMap["orderTime"] = orderInfo.createTime
                for (type in dataDataPayTypeSet) {
                    thisUserPayLogMap[type.typeName] = showMoney(0L)
                }
                //实际付款总额
                var inSumMoney = 0L
                //付款方式处理
                val details = iPayCustomerOrderService.getPayLogDetailList(payLog.id)
                val giftsOfGold =
                    iCustomerInfoService.getGiftsOfGold(payLog.id, TypeEnum.PAY_TYPE_PAY_ORDER)
                for (detail in details) {
                    var payMoney = detail.payMoney
                    if (detail.payType == TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT) {
                        var giftSum = 0L
                        for (gift in giftsOfGold) {
                            giftSum += gift.money
                        }
                        if (giftSum != 0L) {
                            //有馈赠金
                            thisUserPayLogMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(giftSum)
                            if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                                //添加标题
                                titleList.add(
                                    mutableMapOf(
                                        Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                        Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                                    )
                                )
                                //付款类型添加
                                dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                                //之前行数据添加
                                for ((_, list) in userPayLogMap) {
                                    for (logMap in list) {
                                        logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                                    }
                                }
                            }
                            payMoney -= giftSum
                            inSumMoney += giftSum
                        }
                    }
                    thisUserPayLogMap[detail.payType.typeName] = showMoney(payMoney)
                    inSumMoney += payMoney
                    if (!dataDataPayTypeSet.contains(detail.payType)) {
                        //添加标题
                        titleList.add(
                            mutableMapOf(
                                Pair("show", detail.payType.typeName),
                                Pair("name", detail.payType.typeName)
                            )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(detail.payType)
                        //之前数据添加
                        for ((_, list) in userPayLogMap) {
                            for (logMap in list) {
                                logMap[detail.payType.typeName] = showMoney(0L)
                            }
                        }
                    }
                }

                thisUserPayLogMap["inSumMoney"] = showMoney(inSumMoney)
                thisUserPayLogMap["ownUpdate"] = showMoney(originalSumMoney.minus(inSumMoney))
                thisUserPayLogMap["originalSumMoney"] = showMoney(originalSumMoney)
                thisUserPayLogMap["status"] = payLog.type
                thisUserPayLogMap["remark"] = payLog.remark ?: ""
                //添加到map里面去
                userPayLogMap[payLog.createUserId]!!.add(thisUserPayLogMap)

            } else {
                if (payLog.money == 0L) {
                    continue
                }
                //退款
                val refundLogDetails = iPayCustomerOrderService.getRefundLogDetailList(payLog.id)
                if (refundLogDetails.isEmpty()) {
                    //退款必须要有退款明细
                    continue
                }
                //订单实际退款
                var orderRefundSumMoney = 0L
                val flowList = iCustomerInfoService.getCustomerMoneyFlowByAssociateId(
                    payLog.id,
                    TypeEnum.PAY_TYPE_ORDER_REFUND
                )
                for (flow in flowList) {
                    orderRefundSumMoney += flow.money
                }
                //余额退现
                val balanceToMoneyLogs = iCustomerInfoService.getBalanceToMoneyLogBYAssociateId(
                    payLog.id,
                    TypeEnum.PAY_TYPE_ORDER_REFUND_TO_MONEY
                )
                val order = iPayCustomerOrderService.getOrderInfo(payLog.orderId) ?: continue
                if (userMap[payLog.createUserId] == null) {
                    val user = iCompanyUserService.getUser(payLog.createUserId)
                    userMap[payLog.createUserId] = user?.realName ?: ""
                    userPayLogMap[payLog.createUserId] = mutableListOf()
                }
                val customer = iCustomerInfoService.getById(order.customerId)

                val thisUserPayLogMap = mutableMapOf<String, Any>()
                thisUserPayLogMap["customerName"] = customer?.name ?: ""
                thisUserPayLogMap["payTime"] = payLog.payTime
                thisUserPayLogMap["cashierName"] = userMap[payLog.createUserId] ?: ""
                thisUserPayLogMap["orderTime"] = order.createTime

                for (type in dataDataPayTypeSet) {
                    thisUserPayLogMap[type.typeName] = showMoney(0L)
                }
                var balanceToMoneySum = 0L
                for (log in balanceToMoneyLogs) {
                    val payMoney = log.money
                    thisUserPayLogMap[log.payType.typeName] = showMoney(payMoney * -1)
                    balanceToMoneySum += payMoney
                    if (!dataDataPayTypeSet.contains(log.payType)) {
                        //添加标题
                        titleList.add(
                            mutableMapOf(
                                Pair("show", log.payType.typeName),
                                Pair("name", log.payType.typeName)
                            )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(log.payType)
                        //之前数据添加
                        for ((_, list) in userPayLogMap) {
                            for (logMap in list) {
                                logMap[log.payType.typeName] = showMoney(0L)
                            }
                        }
                    }
                }
                val giftsOfGold =
                    iCustomerInfoService.getGiftsOfGold(payLog.id, TypeEnum.PAY_TYPE_ORDER_REFUND)
                var gifts = 0L
                for (gift in giftsOfGold) {
                    gifts += gift.money
                }
                if (gifts != 0L) {
                    thisUserPayLogMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(gifts * -1)
                    if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                        //添加标题
                        titleList.add(
                            mutableMapOf(
                                Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                            )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                        //之前行数据添加
                        for ((_, list) in userPayLogMap) {
                            for (logMap in list) {
                                logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                            }
                        }
                    }
                }

                if (balanceToMoneySum != orderRefundSumMoney) {
                    //订单真实退款 - 退现金额 - 退馈赠金 = 退余额
                    val refundBalance = orderRefundSumMoney - balanceToMoneySum - gifts
                    thisUserPayLogMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] = showMoney(refundBalance * -1)
                    if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)) {
                        //添加标题
                        titleList.add(
                            mutableMapOf(
                                Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName),
                                Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName)
                            )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)
                        //之前行数据添加
                        for ((_, list) in userPayLogMap) {
                            for (logMap in list) {
                                logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] = showMoney(0L)
                            }
                        }
                    }

                }
                //应该付款
                thisUserPayLogMap["originalSumMoney"] = showMoney(payLog.money * -1)

                //实际收款
                thisUserPayLogMap["inSumMoney"] = showMoney(orderRefundSumMoney * -1)

                //欠款变动
                thisUserPayLogMap["ownUpdate"] = showMoney(orderRefundSumMoney - payLog.money)
                thisUserPayLogMap["status"] = payLog.type
                thisUserPayLogMap["remark"] = payLog.remark ?: ""
                //添加到map里面去
                userPayLogMap[payLog.createUserId]!!.add(thisUserPayLogMap)
            }
        }
        //结果整理
        for ((id, list) in userPayLogMap) {
            val userShowMap = mutableMapOf<String, Any?>()
            userShowMap["userName"] = userMap[id]
            userShowMap["list"] = list
            dataList.add(userShowMap)
        }
        titleList.add(mutableMapOf(Pair("show", "欠费变动"), Pair("name", "ownUpdate")))
        titleList.add(mutableMapOf(Pair("show", "状态"), Pair("name", "status")))
        titleList.add(mutableMapOf(Pair("show", "备注"), Pair("name", "remark")))
        resMap["title"] = titleList
        resMap["data"] = dataList
        return returnSuccess(resMap)

    }


    /**
     * 本月对账信息
     */
    @PostMapping("reconciliationForMonth")
    @Transactional
    open fun reconciliationForMonth(@RequestBody vo: ReconciliationSelectVo): ResponseBody {
        if (vo.startTime == null || vo.endTime == null) {
            return returnError(ErrorCode.PARAM_EMPTY, "请选择时间")
        }
        vo.companyId = getContext().companyId
        vo.subCompanyId = getContext().subCompanyId

        val resMap = mutableMapOf<String, BigDecimal>()

        val newAddOwnSumMoney = iPayStatisticalService.getNewAddOwnSumMoney(vo)
        val putAwayOwnSumMoney = iPayStatisticalService.getPutAwayOwnSumMoney(vo)
        val topUpSumMoney = iPayStatisticalService.getTopUpSumMoney(vo)
        val payOrderSumMoney = iPayStatisticalService.getPayOrderSumMoney(vo)
        val onlyTopUpBalanceSumMoney = iPayStatisticalService.getOnlyTopUpBalanceSumMoney(vo)
        //欠款 = 新增欠款 - 收欠款金额
        resMap["ownSumMoney"] = showMoney(newAddOwnSumMoney.minus(putAwayOwnSumMoney))
        resMap["newAddOwnSumMoney"] = showMoney(newAddOwnSumMoney)
        resMap["topUpSumMoney"] = showMoney(topUpSumMoney)
        resMap["payOrderSumMoney"] = showMoney(payOrderSumMoney)
        resMap["onlyTopUpBalanceSumMoney"] = showMoney(onlyTopUpBalanceSumMoney)
        return returnSuccess(resMap)
    }

    /**
     * 按日期对账
     */
    @PostMapping("reconciliationDetailByDay")
    @Transactional
    open fun reconciliationDetailByDay(@RequestBody vo: ReconciliationSelectVo): ResponseBody {
        if (vo.startTime == null || vo.endTime == null) {
            return returnError(ErrorCode.PARAM_EMPTY, "请选择时间")
        }
        vo.companyId = getContext().companyId
        vo.subCompanyId = getContext().subCompanyId
        val dateFormat: DateFormat = SimpleDateFormat("yyyy-MM-dd")
        val days = getDays(dateFormat.format(vo.startTime!!), dateFormat.format(vo.endTime!!))
        //订单支付总额
        val orderPaySumMoneyByDay = iPayStatisticalService.getOrderPaySumMoneyByDay(vo)
        var orderPaySumMoneyByDayIndex = 0
        //收欠款
        val putAwayOwnSumMoneyByDay = iPayStatisticalService.getPutAwayOwnSumMoneyByDay(vo)
        var putAwayOwnSumMoneyByDayIndex = 0
        //新增欠款
        val newAddOwnSumMoneyByDay = iPayStatisticalService.getNewAddOwnSumMoneyByDay(vo)
        var newAddOwnSumMoneyByDayIndex = 0
        //充值余额
        val onlyTopUpBalanceSumMoneyByDay = iPayStatisticalService.getOnlyTopUpBalanceSumMoneyByDay(vo)
        var onlyTopUpBalanceSumMoneyByDayIndex = 0
        //订单充值（因支付订单生成的充值 ）
        val topUpForPayOrderSumMoneyByDay = iPayStatisticalService.getTopUpForPayOrderSumMoneyByDay(vo)
        var topUpForPayOrderSumMoneyByDayIndex = 0
        //充值退款
        val onlyBalanceToMoneySumByDay = iPayStatisticalService.getOnlyBalanceToMoneySumByDay(vo)
        var onlyBalanceToMoneySumIndex = 0
        //订单退款
        val orderBalanceToMoneySumByDay = iPayStatisticalService.getOrderBalanceToMoneySumByDay(vo)
        var orderBalanceToMoneySumIndex = 0
        //订单退款至余额
        val orderRefundToBalanceSumMoneyByDay = iPayStatisticalService.getOrderRefundToBalanceSumMoneyByDay(vo)
        var orderRefundToBalanceSumMoneyIndex = 0
        //订单退款至现金
        val orderRefundToMoneySumMoneyByDay = iPayStatisticalService.getOrderRefundToMoneySumMoneyByDay(vo)
        var orderRefundToMoneySumMoneyIndex = 0

        val resList = mutableListOf<MutableMap<String, Any>>()
        for (dayStr in days) {
            val resMap = mutableMapOf<String, Any>()
            resMap["dayStr"] = dayStr
            //诊疗收款
            var orderPaySumMoney = 0L
            if (orderPaySumMoneyByDayIndex < orderPaySumMoneyByDay.size) {
                if (orderPaySumMoneyByDay[orderPaySumMoneyByDayIndex].payDay == dayStr) {
                    orderPaySumMoney = orderPaySumMoneyByDay[orderPaySumMoneyByDayIndex].sumMoney
                    orderPaySumMoneyByDayIndex++
                }
            }
            //收欠款
            var putAwayOwnSumMoney = 0L
            if (putAwayOwnSumMoneyByDayIndex < putAwayOwnSumMoneyByDay.size) {
                if (putAwayOwnSumMoneyByDay[putAwayOwnSumMoneyByDayIndex].payDay == dayStr) {
                    putAwayOwnSumMoney = putAwayOwnSumMoneyByDay[putAwayOwnSumMoneyByDayIndex].sumMoney
                    putAwayOwnSumMoneyByDayIndex++
                }
            }
            //新增欠款
            var newAddOwnSumMoney = 0L
            if (newAddOwnSumMoneyByDayIndex < newAddOwnSumMoneyByDay.size) {
                if (newAddOwnSumMoneyByDay[newAddOwnSumMoneyByDayIndex].payDay == dayStr) {
                    newAddOwnSumMoney = newAddOwnSumMoneyByDay[newAddOwnSumMoneyByDayIndex].sumMoney
                    newAddOwnSumMoneyByDayIndex++
                }
            }
            //充值
            var onlyTopUpBalanceSumMoney = 0L
            if (onlyTopUpBalanceSumMoneyByDayIndex < onlyTopUpBalanceSumMoneyByDay.size) {
                if (onlyTopUpBalanceSumMoneyByDay[onlyTopUpBalanceSumMoneyByDayIndex].payDay == dayStr) {
                    onlyTopUpBalanceSumMoney =
                        onlyTopUpBalanceSumMoneyByDay[onlyTopUpBalanceSumMoneyByDayIndex].sumMoney
                    onlyTopUpBalanceSumMoneyByDayIndex++
                }
            }
            //订单付款充值
            var topUpForPayOrderSumMoney = 0L
            if (topUpForPayOrderSumMoneyByDayIndex < topUpForPayOrderSumMoneyByDay.size) {
                if (topUpForPayOrderSumMoneyByDay[topUpForPayOrderSumMoneyByDayIndex].payDay == dayStr) {
                    topUpForPayOrderSumMoney =
                        topUpForPayOrderSumMoneyByDay[topUpForPayOrderSumMoneyByDayIndex].sumMoney
                    topUpForPayOrderSumMoneyByDayIndex++
                }
            }
            //余额退款
            var onlyBalanceToMoneySum = 0L
            if (onlyBalanceToMoneySumIndex < onlyBalanceToMoneySumByDay.size) {
                if (onlyBalanceToMoneySumByDay[onlyBalanceToMoneySumIndex].payDay == dayStr) {
                    onlyBalanceToMoneySum = onlyBalanceToMoneySumByDay[onlyBalanceToMoneySumIndex].sumMoney
                    onlyBalanceToMoneySumIndex++
                }
            }
            //订单退款（从余额变动记录里面算）
            var orderBalanceToMoneySum = 0L
            if (orderBalanceToMoneySumIndex < orderBalanceToMoneySumByDay.size) {
                if (orderBalanceToMoneySumByDay[orderBalanceToMoneySumIndex].payDay == dayStr) {
                    orderBalanceToMoneySum = orderBalanceToMoneySumByDay[orderBalanceToMoneySumIndex].sumMoney
                    orderBalanceToMoneySumIndex++
                }
            }
            //订单退款成余额
            var orderRefundToBalanceSumMoney = 0L
            if (orderRefundToBalanceSumMoneyIndex < orderRefundToBalanceSumMoneyByDay.size) {
                if (orderRefundToBalanceSumMoneyByDay[orderRefundToBalanceSumMoneyIndex].payDay == dayStr) {
                    orderRefundToBalanceSumMoney =
                        orderRefundToBalanceSumMoneyByDay[orderRefundToBalanceSumMoneyIndex].sumMoney
                    orderRefundToBalanceSumMoneyIndex++
                }
            }
            //订单退成现金
            var orderRefundToMoneySumMoney = 0L
            if (orderRefundToMoneySumMoneyIndex < orderRefundToMoneySumMoneyByDay.size) {
                if (orderRefundToBalanceSumMoneyByDay[orderRefundToMoneySumMoneyIndex].payDay == dayStr) {
                    orderRefundToMoneySumMoney =
                        orderRefundToMoneySumMoneyByDay[orderRefundToMoneySumMoneyIndex].sumMoney
                    orderRefundToMoneySumMoneyIndex++
                }
            }


            //订单收款整合
            resMap["topUpForPayOrderSumMoney"] = showMoney(topUpForPayOrderSumMoney)
            resMap["orderRefundToMoneySumMoney"] = showMoney(orderRefundToMoneySumMoney)
            resMap["orderTopSumMoney"] = showMoney(topUpForPayOrderSumMoney.minus(orderRefundToMoneySumMoney))

            //欠款整合
            resMap["putAwayOwnSumMoney"] = showMoney(putAwayOwnSumMoney)
            resMap["newAddOwnSumMoney"] = showMoney(newAddOwnSumMoney)
            resMap["OwnSumMoney"] = showMoney(newAddOwnSumMoney.minus(putAwayOwnSumMoney))

            //现金流入整合
            resMap["topUp"] = showMoney(
                onlyTopUpBalanceSumMoney.plus(topUpForPayOrderSumMoney).minus(onlyBalanceToMoneySum)
                    .minus(orderBalanceToMoneySum)
            )
            resMap["onlyTopUpBalanceSumMoney"] = showMoney(onlyTopUpBalanceSumMoney)
            resMap["topUpForPayOrderSumMoney"] = showMoney(topUpForPayOrderSumMoney)
            resMap["onlyBalanceToMoneySum"] = showMoney(topUpForPayOrderSumMoney)
            resMap["orderBalanceToMoneySum"] = showMoney(topUpForPayOrderSumMoney)

            //订单收入整合
            resMap["orderPaySumMoney"] = showMoney(orderPaySumMoney)
            resMap["orderRefundSMoney"] = showMoney(orderRefundToBalanceSumMoney.plus(orderRefundToMoneySumMoney))
            resMap["orderSumMoney"] =
                showMoney(orderPaySumMoney.minus(orderRefundToBalanceSumMoney.plus(orderRefundToMoneySumMoney)))

            resList.add(resMap)
        }

        return returnSuccess(resList)
    }

    @PostMapping("billDetails")
    @Transactional
    open fun billDetails(@RequestBody vo: DailyCheckForSelectVo): ResponseBody {
        val page = iPayStatisticalService.getPayCustomerOrderPayAndRefundLogPage(vo)
        //返回参数
        val resMap = mutableMapOf<String, Any>()
        val userMap = mutableMapOf<Long, String>()
        //标题
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "病历号"), Pair("name", "sickNum")))
        titleList.add(mutableMapOf(Pair("show", "账单号"), Pair("name", "orderNum")))
        titleList.add(mutableMapOf(Pair("show", "单据号"), Pair("name", "payNum")))
        titleList.add(mutableMapOf(Pair("show", "患者姓名"), Pair("name", "customerName")))
        titleList.add(mutableMapOf(Pair("show", "患者性别"), Pair("name", "gander")))
        titleList.add(mutableMapOf(Pair("show", "患者手机"), Pair("name", "mobile")))
        titleList.add(mutableMapOf(Pair("show", "收费状态"), Pair("name", "payStatus")))
        titleList.add(mutableMapOf(Pair("show", "收费时间"), Pair("name", "payTime")))
        titleList.add(mutableMapOf(Pair("show", "收款人"), Pair("name", "payUserName")))
        titleList.add(mutableMapOf(Pair("show", "收费项目"), Pair("name", "payItems")))
        titleList.add(mutableMapOf(Pair("show", "医生"), Pair("name", "doctorNames")))
        titleList.add(mutableMapOf(Pair("show", "护士"), Pair("name", "nurseNames")))
        titleList.add(mutableMapOf(Pair("show", "咨询师"), Pair("name", "conNames")))
        titleList.add(mutableMapOf(Pair("show", "备注"), Pair("name", "remark")))
        titleList.add(mutableMapOf(Pair("show", "应付"), Pair("name", "originalSumMoney")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))



        //结果数据
        val dataList = mutableListOf<MutableMap<String, Any>>()
        //付款类型
        val dataDataPayTypeSet = mutableSetOf<TypeEnum>()
        for (log in page.records) {
            val order = iPayCustomerOrderService.getOrderInfo(log.orderId)
            val orderDetails = iPayCustomerOrderService.getDetailList(log.orderId)

            val customer = iCustomerInfoService.getById(order?.customerId ?: 0L)
            if (customer != null) {
                iCustomerInfoService.getMobileStr(customer)
            }
            val resDataMap = mutableMapOf<String, Any>()
            resDataMap["sickNum"] = customer?.historySickNum ?: ""
            resDataMap["orderNum"] = order?.orderNum ?: ""
            resDataMap["payNum"] = log.payNum ?: ""
            resDataMap["customerName"] = customer?.name ?: ""
            resDataMap["gander"] = customer?.gender ?: ""
            resDataMap["mobile"] = customer?.mobileNumStr ?: ""
            resDataMap["payStatus"] = log.type
            resDataMap["payTime"] = log?.payTime ?: ""
            resDataMap["payUserName"] = getUserByMap(log.createUserId, userMap) ?: ""
            val itemNames = StringBuffer()
            val doctorNames = StringBuffer()
            val nurseNames = StringBuffer()
            val conNames = StringBuffer()
            val doctorIdSet = mutableSetOf<Long>()
            val nurseIdSet = mutableSetOf<Long>()
            val conIdSet = mutableSetOf<Long>()
            for (orderDetail in orderDetails) {
                itemNames.append(orderDetail.itemName).append(" ")
                if(orderDetail.doctorId != null && !doctorIdSet.contains(orderDetail.doctorId )){
                    doctorIdSet.add(orderDetail.doctorId!!)
                    val doctorName = getUserByMap(orderDetail.doctorId, userMap)
                    if (doctorName != null) {
                        doctorNames.append(doctorName).append(" ")
                    }
                }
                if(orderDetail.nurseId != null && !nurseIdSet.contains(orderDetail.nurseId )){
                    nurseIdSet.add(orderDetail.nurseId!!)
                    val nurseName = getUserByMap(orderDetail.nurseId, userMap)
                    if (nurseName != null) {
                        nurseNames.append(nurseName).append(" ")
                    }
                }
                if(orderDetail.consultantId != null && !conIdSet.contains(orderDetail.consultantId )){
                    conIdSet.add(orderDetail.consultantId!!)
                    val conName = getUserByMap(orderDetail.consultantId, userMap)
                    if (conName != null) {
                        conNames.append(conName).append(" ")
                    }
                }

            }
            resDataMap["payItems"] = itemNames.toString()
            resDataMap["doctorNames"] = doctorNames.toString()
            resDataMap["nurseNames"] = nurseNames.toString()
            resDataMap["conNames"] = conNames.toString()
            resDataMap["remark"] = log?.remark ?: ""
            if (log.type != TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_REFUND) {
                val payDetails = iPayCustomerOrderService.getPayLogDetailList(log.id)
                for (type in dataDataPayTypeSet) {
                    resDataMap[type.typeName] = showMoney(0L)
                }
                var inSumMoney = 0L
                for (payDetail in payDetails) {
                    inSumMoney += payDetail.payMoney
                    var payMoney = payDetail.payMoney
                    if (payDetail.payType == TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT) {
                        var giftsSum = 0L
                        val giftsOfGold =
                            iCustomerInfoService.getGiftsOfGold(log.id, TypeEnum.PAY_TYPE_PAY_ORDER)
                        for (gift in giftsOfGold) {
                            giftsSum += gift.money
                        }
                        if (giftsSum != 0L) {
                            //有馈赠金
                            resDataMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(giftsSum)
                            if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                                titleList.add(
                                    mutableMapOf(
                                        Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                        Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                                    )
                                )
                                //付款类型添加
                                dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                                //之前数据添加
                                for (logMap in dataList) {
                                    logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                                }
                            }
                        }
                        payMoney -= giftsSum
                    }
                    resDataMap[payDetail.payType.typeName] = showMoney(payMoney)
                    if (!dataDataPayTypeSet.contains(payDetail.payType)) {
                        titleList.add(
                            mutableMapOf(
                                Pair("show", payDetail.payType.typeName),
                                Pair("name", payDetail.payType.typeName)
                            )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(payDetail.payType)
                        //之前数据添加
                        for (logMap in dataList) {
                            logMap[payDetail.payType.typeName] = showMoney(0L)
                        }
                    }
                }
                //实收
                resDataMap["inSumMoney"] = showMoney(inSumMoney)
                if (log.type == TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_OWE) {
                    resDataMap["originalSumMoney"] = showMoney(0)
                } else {
                    resDataMap["originalSumMoney"] = showMoney(order?.orderDetailSumMoney ?: 0)
                }

            } else {
                if (log.money == 0L) {
                    continue
                }
                //退款
                val refundLogDetails = iPayCustomerOrderService.getRefundLogDetailList(log.id)
                if (refundLogDetails.isEmpty()) {
                    //退款必须要有退款明细
                    continue
                }
                //订单实际退款
                var orderRefundSumMoney = 0L
                val flowList = iCustomerInfoService.getCustomerMoneyFlowByAssociateId(
                    log.id,
                    TypeEnum.PAY_TYPE_ORDER_REFUND
                )
                for (flow in flowList) {
                    orderRefundSumMoney += flow.money
                }
                //余额退现
                val balanceToMoneyLogs = iCustomerInfoService.getBalanceToMoneyLogBYAssociateId(
                    log.id,
                    TypeEnum.PAY_TYPE_ORDER_REFUND_TO_MONEY
                )
                for (type in dataDataPayTypeSet) {
                    resDataMap[type.typeName] = showMoney(0L)
                }
                //退现金记录
                var balanceToMoneySum = 0L
                for (log in balanceToMoneyLogs) {
                    val payMoney = log.money
                    resDataMap[log.payType.typeName] = showMoney(payMoney * -1)
                    balanceToMoneySum += payMoney
                    if (!dataDataPayTypeSet.contains(log.payType)) {
                        //添加标题
                        titleList.add(
                            mutableMapOf(
                                Pair("show", log.payType.typeName),
                                Pair("name", log.payType.typeName)
                            )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(log.payType)
                        //之前数据添加
                        for (logMap in dataList) {
                            logMap[log.payType.typeName] = showMoney(0L)
                        }
                    }
                }
                if (orderRefundSumMoney != balanceToMoneySum) {
                    val giftsOfGold =
                        iCustomerInfoService.getGiftsOfGold(log.id, TypeEnum.PAY_TYPE_ORDER_REFUND)
                    var gifts = 0L
                    for (gift in giftsOfGold) {
                        gifts += gift.money
                    }
                    if (gifts != 0L) {
                        resDataMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(gifts * -1)
                        if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                            //添加标题
                            titleList.add(
                                mutableMapOf(
                                    Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                    Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                                )
                            )
                            //付款类型添加
                            dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                            for (logMap in dataList) {
                                logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                            }
                        }
                    }
                    var refundBalance = orderRefundSumMoney - balanceToMoneySum - gifts
                    resDataMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] = showMoney(refundBalance * -1)
                    if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)) {
                        //添加标题
                        titleList.add(
                            mutableMapOf(
                                Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName),
                                Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName)
                            )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)
                        //之前行数据添加
                        for (logMap in dataList) {
                            logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] = showMoney(0L)
                        }

                    }
                }
                //应该付款
                resDataMap["originalSumMoney"] =
                    showMoney(log.money * -1)
                //实际收款
                resDataMap["inSumMoney"] =
                    showMoney(orderRefundSumMoney * -1)
            }
            dataList.add(resDataMap)

        }
        resMap["page"] = page
        resMap["title"] = titleList
        resMap["data"] = dataList

        return returnSuccess(resMap)
    }

    /**
     * 账单明细导出
     */
    @PostMapping("billDetailsExport")
    @Transactional
    open fun billDetailsExport(@RequestBody vo: DailyCheckForSelectVo,response: HttpServletResponse) {
        val page = iPayStatisticalService.getPayCustomerOrderPayAndRefundLogExport(vo)
        //返回参数
        val resMap = mutableMapOf<String, Any>()
        val userMap = mutableMapOf<Long, String>()
        //标题
        val titleList = mutableListOf<Map<String, Any>>()
        titleList.add(mutableMapOf(Pair("show", "病历号"), Pair("name", "sickNum")))
        titleList.add(mutableMapOf(Pair("show", "账单号"), Pair("name", "orderNum")))
        titleList.add(mutableMapOf(Pair("show", "单据号"), Pair("name", "payNum")))
        titleList.add(mutableMapOf(Pair("show", "患者姓名"), Pair("name", "customerName")))
        titleList.add(mutableMapOf(Pair("show", "患者性别"), Pair("name", "gander")))
        titleList.add(mutableMapOf(Pair("show", "患者手机"), Pair("name", "mobile")))
        titleList.add(mutableMapOf(Pair("show", "收费状态"), Pair("name", "payStatus")))
        titleList.add(mutableMapOf(Pair("show", "收费时间"), Pair("name", "payTime")))
        titleList.add(mutableMapOf(Pair("show", "收款人"), Pair("name", "payUserName")))
        titleList.add(mutableMapOf(Pair("show", "收费项目"), Pair("name", "payItems")))
        titleList.add(mutableMapOf(Pair("show", "医生"), Pair("name", "doctorNames")))
        titleList.add(mutableMapOf(Pair("show", "护士"), Pair("name", "nurseNames")))
        titleList.add(mutableMapOf(Pair("show", "咨询师"), Pair("name", "conNames")))
        titleList.add(mutableMapOf(Pair("show", "备注"), Pair("name", "remark")))
        titleList.add(mutableMapOf(Pair("show", "应付"), Pair("name", "originalSumMoney")))
        titleList.add(mutableMapOf(Pair("show", "实收"), Pair("name", "inSumMoney")))



        //结果数据
        val dataList = mutableListOf<MutableMap<String, Any>>()
        //付款类型
        val dataDataPayTypeSet = mutableSetOf<TypeEnum>()
        for (log in page) {
            val order = iPayCustomerOrderService.getOrderInfo(log.orderId)
            val orderDetails = iPayCustomerOrderService.getDetailList(log.orderId)

            val customer = iCustomerInfoService.getById(order?.customerId ?: 0L)
            if (customer != null) {
                iCustomerInfoService.getMobileStr(customer)
            }
            val resDataMap = mutableMapOf<String, Any>()
            resDataMap["sickNum"] = customer?.historySickNum ?: ""
            resDataMap["orderNum"] = order?.orderNum ?: ""
            resDataMap["payNum"] = log.payNum ?: ""
            resDataMap["customerName"] = customer?.name ?: ""
            resDataMap["gander"] = customer?.gender?.typeName ?: ""
            resDataMap["mobile"] = customer?.mobileNumStr ?: ""
            resDataMap["payStatus"] = log.type.typeName
            resDataMap["payTime"] = log?.payTime ?: ""
            resDataMap["payUserName"] = getUserByMap(log.createUserId, userMap) ?: ""
            val itemNames = StringBuffer()
            val doctorNames = StringBuffer()
            val nurseNames = StringBuffer()
            val conNames = StringBuffer()
            val doctorIdSet = mutableSetOf<Long>()
            val nurseIdSet = mutableSetOf<Long>()
            val conIdSet = mutableSetOf<Long>()
            for (orderDetail in orderDetails) {
                itemNames.append(orderDetail.itemName).append(" ")
                if(orderDetail.doctorId != null && !doctorIdSet.contains(orderDetail.doctorId )){
                    doctorIdSet.add(orderDetail.doctorId!!)
                    val doctorName = getUserByMap(orderDetail.doctorId, userMap)
                    if (doctorName != null) {
                        doctorNames.append(doctorName).append(" ")
                    }
                }
                if(orderDetail.nurseId != null && !nurseIdSet.contains(orderDetail.nurseId )){
                    nurseIdSet.add(orderDetail.nurseId!!)
                    val nurseName = getUserByMap(orderDetail.nurseId, userMap)
                    if (nurseName != null) {
                        nurseNames.append(nurseName).append(" ")
                    }
                }
                if(orderDetail.consultantId != null && !conIdSet.contains(orderDetail.consultantId )){
                    conIdSet.add(orderDetail.consultantId!!)
                    val conName = getUserByMap(orderDetail.consultantId, userMap)
                    if (conName != null) {
                        conNames.append(conName).append(" ")
                    }
                }

            }
            resDataMap["payItems"] = itemNames.toString()
            resDataMap["doctorNames"] = doctorNames.toString()
            resDataMap["nurseNames"] = nurseNames.toString()
            resDataMap["conNames"] = conNames.toString()
            resDataMap["remark"] = log?.remark ?: ""
            if (log.type != TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_REFUND) {
                val payDetails = iPayCustomerOrderService.getPayLogDetailList(log.id)
                for (type in dataDataPayTypeSet) {
                    resDataMap[type.typeName] = showMoney(0L)
                }
                var inSumMoney = 0L
                for (payDetail in payDetails) {
                    inSumMoney += payDetail.payMoney
                    var payMoney = payDetail.payMoney
                    if (payDetail.payType == TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT) {
                        var giftsSum = 0L
                        val giftsOfGold =
                                iCustomerInfoService.getGiftsOfGold(log.id, TypeEnum.PAY_TYPE_PAY_ORDER)
                        for (gift in giftsOfGold) {
                            giftsSum += gift.money
                        }
                        if (giftsSum != 0L) {
                            //有馈赠金
                            resDataMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(giftsSum)
                            if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                                titleList.add(
                                        mutableMapOf(
                                                Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                                Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                                        )
                                )
                                //付款类型添加
                                dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                                //之前数据添加
                                for (logMap in dataList) {
                                    logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                                }
                            }
                        }
                        payMoney -= giftsSum
                    }
                    resDataMap[payDetail.payType.typeName] = showMoney(payMoney)
                    if (!dataDataPayTypeSet.contains(payDetail.payType)) {
                        titleList.add(
                                mutableMapOf(
                                        Pair("show", payDetail.payType.typeName),
                                        Pair("name", payDetail.payType.typeName)
                                )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(payDetail.payType)
                        //之前数据添加
                        for (logMap in dataList) {
                            logMap[payDetail.payType.typeName] = showMoney(0L)
                        }
                    }
                }
                //实收
                resDataMap["inSumMoney"] = showMoney(inSumMoney)
                if (log.type == TypeEnum.PAY_ORDER_PAY_LOG_PAY_TYPE_OWE) {
                    resDataMap["originalSumMoney"] = showMoney(0)
                } else {
                    resDataMap["originalSumMoney"] = showMoney(order?.orderDetailSumMoney ?: 0)
                }

            } else {
                if (log.money == 0L) {
                    continue
                }
                //退款
                val refundLogDetails = iPayCustomerOrderService.getRefundLogDetailList(log.id)
                if (refundLogDetails.isEmpty()) {
                    //退款必须要有退款明细
                    continue
                }
                //订单实际退款
                var orderRefundSumMoney = 0L
                val flowList = iCustomerInfoService.getCustomerMoneyFlowByAssociateId(
                        log.id,
                        TypeEnum.PAY_TYPE_ORDER_REFUND
                )
                for (flow in flowList) {
                    orderRefundSumMoney += flow.money
                }
                //余额退现
                val balanceToMoneyLogs = iCustomerInfoService.getBalanceToMoneyLogBYAssociateId(
                        log.id,
                        TypeEnum.PAY_TYPE_ORDER_REFUND_TO_MONEY
                )
                for (type in dataDataPayTypeSet) {
                    resDataMap[type.typeName] = showMoney(0L)
                }
                //退现金记录
                var balanceToMoneySum = 0L
                for (log in balanceToMoneyLogs) {
                    val payMoney = log.money
                    resDataMap[log.payType.typeName] = showMoney(payMoney * -1)
                    balanceToMoneySum += payMoney
                    if (!dataDataPayTypeSet.contains(log.payType)) {
                        //添加标题
                        titleList.add(
                                mutableMapOf(
                                        Pair("show", log.payType.typeName),
                                        Pair("name", log.payType.typeName)
                                )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(log.payType)
                        //之前数据添加
                        for (logMap in dataList) {
                            logMap[log.payType.typeName] = showMoney(0L)
                        }
                    }
                }
                if (orderRefundSumMoney != balanceToMoneySum) {
                    val giftsOfGold =
                            iCustomerInfoService.getGiftsOfGold(log.id, TypeEnum.PAY_TYPE_ORDER_REFUND)
                    var gifts = 0L
                    for (gift in giftsOfGold) {
                        gifts += gift.money
                    }
                    if (gifts != 0L) {
                        resDataMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(gifts * -1)
                        if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)) {
                            //添加标题
                            titleList.add(
                                    mutableMapOf(
                                            Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName),
                                            Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName)
                                    )
                            )
                            //付款类型添加
                            dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                            for (logMap in dataList) {
                                logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(0L)
                            }
                        }
                    }
                    var refundBalance = orderRefundSumMoney - balanceToMoneySum - gifts
                    resDataMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] = showMoney(refundBalance * -1)
                    if (!dataDataPayTypeSet.contains(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)) {
                        //添加标题
                        titleList.add(
                                mutableMapOf(
                                        Pair("show", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName),
                                        Pair("name", TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName)
                                )
                        )
                        //付款类型添加
                        dataDataPayTypeSet.add(TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT)
                        //之前行数据添加
                        for (logMap in dataList) {
                            logMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT.typeName] = showMoney(0L)
                        }

                    }
                }
                //应该付款
                resDataMap["originalSumMoney"] =
                        showMoney(log.money * -1)
                //实际收款
                resDataMap["inSumMoney"] =
                        showMoney(orderRefundSumMoney * -1)
            }
            dataList.add(resDataMap)

        }
        //导出
        val headAlias: MutableMap<String?, String?> = MapUtil.newHashMap(true)
        for ( map in titleList){
            headAlias[map["name"].toString()]= map["show"].toString()
        }
        export(response,dataList,headAlias)
    }



    private fun getUserByMap(id: Long?, userMap: MutableMap<Long, String>): String? {
        return if (id == null) {
            return null
        } else if (userMap[id] != null) {
            userMap[id]
        } else {
            val user = iCompanyUserService.getUser(id)
            if (user == null) {
                null
            } else {
                userMap[id] = user.realName
                user.realName
            }
        }

    }

    private fun setPayMoney(
        list: List<StatisticalBalanceInLogDto>,
        resDataMap: MutableMap<String, Any>,
        dataPayTypeSet: MutableSet<TypeEnum>,
        titleList: MutableList<Map<String, Any>>,
        dataList: MutableList<MutableMap<String, Any>>,
        giftUse: Map<String, Long>?,
        dayStr: String,
    ): Long {
        var inSumMoney = 0L
        val useGift = giftUse != null
        for (inLog in list) {
            if (useGift && giftUse != null && inLog.payType == TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT) {
                if (giftUse[dayStr] != null && giftUse[dayStr] != 0L) {
                    // 如果用了馈赠金
                    valTitle(dataPayTypeSet, titleList, dataList, TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT)
                    resDataMap[inLog.payType.typeName] = showMoney(inLog.inSumMoney - giftUse[dayStr]!!)
                    resDataMap[TypeEnum.CUSTOMER_PAY_TYPE_ACCOUNT_GIFT.typeName] = showMoney(giftUse[dayStr]!!)
                }
            } else {
                resDataMap[inLog.payType.typeName] = showMoney(inLog.inSumMoney)
            }
            inSumMoney += inLog.inSumMoney

            valTitle(dataPayTypeSet, titleList, dataList, inLog.payType)

        }
        return inSumMoney
    }

    /**
     * 验证头部，如果有，就不管，没有，就处理
     */
    fun valTitle(
        dataPayTypeSet: MutableSet<TypeEnum>,
        titleList: MutableList<Map<String, Any>>,
        dataList: MutableList<MutableMap<String, Any>>,
        payType: TypeEnum
    ) {
        if (!dataPayTypeSet.contains(payType)) {
            //新的付款类型
            //添加标题
            titleList.add(
                mutableMapOf(
                    Pair("show", payType.typeName),
                    Pair("name", payType.typeName)
                )
            )
            //付款类型添加
            dataPayTypeSet.add(payType)
            //之前数据添加
            for (data in dataList) {
                data[payType.typeName] = showMoney(0L)
            }
        }
    }

    /**
     * 循环
     */
    private fun eachStatisticalBalanceInLogByTypeList(
        list: List<StatisticalBalanceInLogByTypeDto>,
        payTypeActualPaymentMap: MutableMap<TypeEnum, Long>,
        dataMap: MutableMap<TypeEnum, MutableMap<String, Long>>,
        title: String
    ) {
        for (log in list) {
            if (payTypeActualPaymentMap[log.payType] == null) {
                payTypeActualPaymentMap[log.payType] = log.money
                dataMap[log.payType] = createPayType()
            } else {
                payTypeActualPaymentMap[log.payType] = payTypeActualPaymentMap[log.payType]!! + log.money
            }
            dataMap[log.payType]!![title] = log.money
        }
    }

    /**
     * 新的一列
     */
    private fun createPayType(): MutableMap<String, Long> {
        val map = mutableMapOf<String, Long>()
        map["诊疗收费"] = 0
        map["诊疗收欠费"] = 0
        map["诊疗退费"] = 0
        map["余额充值"] = 0
        map["余额退费"] = 0
        return map
    }


    private fun showMoney(money: Long): BigDecimal {
        return BigDecimal(money.div(Constants.OtherConfig.MONEY_TO_DB_DOUBLE)).setScale(2, RoundingMode.HALF_UP)
    }

    private fun showMoney(payMoney: Long, selfMoney: Long, allMoney: Long): BigDecimal {
        if (allMoney.toInt() == 0) {
            return BigDecimal(0)
        }
        val selfPayMoney = payMoney.times(selfMoney).div(allMoney)
        return BigDecimal(selfPayMoney.div(Constants.OtherConfig.MONEY_TO_DB_DOUBLE)).setScale(2, RoundingMode.HALF_UP)
    }


}

